#ifndef BURNER_WIN32_H
#define BURNER_WIN32_H

#define _WIN32_WINNT 0x0500
#define _WIN32_IE 0x0500
#define STRICT

#ifdef _UNICODE
 #define UNICODE
#endif

#define WIN32_LEAN_AND_MEAN
#define OEMRESOURCE
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <commdlg.h>
#include <mmsystem.h>
#include <process.h>

// Additions to the Cygwin/MinGW win32 headers
#ifdef __GNUC__
 #include "mingw_win32.h"
#endif

#include "resource.h"
#include "resource_string.h"

// ---------------------------------------------------------------------------
// use STL
#include <string>
#include <list>
#include <set>
#include <map>
#include <string>
#include <vector>
#include <hash_map>
using std::string;
using std::wstring;
using std::list;
using std::set;
using std::map;
using std::vector;
using std::multimap;
using stdext::hash_map;

#ifndef MAX_PATH
 #define MAX_PATH (260)
#endif

// ---------------------------------------------------------------------------

#define SEPERATOR_1 L" - "
#define SEPERATOR_2 L" ~ "
#define WRITE_UNICODE_BOM(file) { UINT16 BOM[] = { 0xfeff }; fwrite(BOM, 2, 1, file); }

#define KEY_DOWN(Code) ((GetAsyncKeyState(Code) & 0x8000) ? 1 : 0)

// ---------------------------------------------------------------------------
// includes
#include "strconv.h"
#include "auditstate.h"
#include "menu.h"
#include "localise.h"
#include "dialogmanager.h"
#include "preference.h"
#include "misc_win32.h"
#include "progress.h"
#include "romloader.h"
#include "vid_directx_support.h"
#ifndef NO_IPS
#include "patch.h"
#endif

// ---------------------------------------------------------------------------
// from burn
extern int bsavedecryptedcs;
extern int bsavedecryptedps;
extern int bsavedecrypteds1;
extern int bsavedecryptedvs;
extern int bsavedecryptedm1;
extern int bsavedecryptedxor;
extern int bsavedecryptedprom;

// main.cpp
extern HINSTANCE hAppInst;			// Application Instance
extern HANDLE hMainThread;			// Handle to the main thread
extern int appThreadPriority;
extern int appShowCmd;

#define EXE_NAME_SIZE (32)
extern wchar_t appExeName[EXE_NAME_SIZE + 1];
extern wchar_t appBurnVer[16];

extern bool alwaysProcessKey;

// Used for the load/save dialog in commdlg.h
extern wchar_t commonChoice[MAX_PATH];	// File chosen by the user
extern OPENFILENAME ofn;

int dprintf(char* pszFormat, ...);	// Use instead of printf() in the UI

void appCleanup();
int appMessage(MSG* pMsg);
bool appProcessKeyboardInput();

// popup_win32.cpp
enum FBAPopupType { MT_NONE = 0, MT_ERROR, MT_WARNING, MT_INFO };

#define PUF_TYPE_ERROR			(1)
#define PUF_TYPE_WARNING		(2)
#define PUF_TYPE_INFO			(3)
#define PUF_TYPE_LOGONLY		(8)
#define PUF_TEXT_TRANSLATE		(1 << 16)
#define PUF_TEXT_NO_TRANSLATE	(0)
#define PUF_TEXT_DEFAULT		(PUF_TEXT_TRANSLATE)

int FBAPopupDisplay(int nFlags);
int FBAPopupAddText(int nFlags, wchar_t* pszFormat, ...);
int FBAPopupDestroyText();

// systeminfo.cpp
LONG CALLBACK ExceptionFilter(_EXCEPTION_POINTERS* pExceptionInfo);
int systemInfoCreate(HWND);

// splash.cpp
extern int splashTime;
extern int disableSplash;
int splashCreate();
void splashDestroy(bool bForce);

// about.cpp
int aboutCreate(HWND);

// media.cpp
int mediaInit();
int mediaExit();
int mediaChangeFps(int scale);
int mediaReInit();
int mediaReInitAudio();

// drv.cpp
extern int driverOkay;				// 1 if the Driver has been initted okay, and it's okay to use the BurnDrv functions
int BurnerDrvInit(int nDrvNum, bool bRestore);
int drvInitCallback();				// Used when Burn library needs to load a game. DrvInit(nBurnSelect, false)
int BurnerDrvExit();

// run.cpp
extern int appVirtualFps;			// virtual fps
extern int runPause;
extern int autoFrameSkip;
extern bool showFPS;
extern bool appDoFast;
extern bool appDoStep;
extern unsigned int fastSpeed;
extern int showEffect;

int runIdle();
int runMessageLoop();
int runInit();
int runExit();
int runReset();

// scrn.cpp
extern HWND hScrnWnd;				// Handle to the screen window
extern bool showOnTop;
extern bool fullscreenOnStart;
extern HWND hVideoWnd;				// Handle to the video window

extern int autoPause;
extern int scrnWindowSize;
extern RECT systemWorkArea;			// The full screen area
extern int windowPosX, windowPosY;
extern int savestateSlot;

int scrnInit();
int scrnExit();
int scrnSize();
int scrnTitle();
int scrnSwitchFull();
int scrnFakeFullscreen();
int scrnSetFull(bool full);
void __cdecl scrnReinit();
void setPauseMode(bool bPause);
void simpleReinitScrn(bool);

// sel.cpp
extern HWND hSelDlg;
extern int loadMenuShowX;
extern int loadDriverShowX;
extern int loadTabSel;
extern wchar_t userFilterStr[MAX_PATH];
extern int loadSystemSel;
int selDialog(HWND);				// Choose a Burn driver
void clearNodeInfo();
int driverConfigDialog(HWND);		// Driver config

// translist.cpp
extern wchar_t transGamelistFile[MAX_PATH];
int loadGamelist();
int createGamelist();
const wchar_t* transGameName(const char* oldName, unsigned index = ~0U);

// conc.cpp
int configCheatLoad(const wchar_t* filename = NULL);
int configCheatReload(const wchar_t* filename = NULL);

// wave.cpp
extern bool soundLogStart;
int waveLogStart();
int waveLogStop();
void waveLogWrite();

// inpd.cpp
int inpdUpdate();
int inpdCreate();
int inpdListMake(int build);
int loadDefaultInput();

// inpcheat.cpp
int inpCheatCreate();

// inpdipsw.cpp
void inpDIPSWResetDIPs();
int inpDIPSWCreate();

// inpjukebox.cpp
int jukeCreate();
void jukeDestroy();

// inps.cpp
extern unsigned int inpsInput;
int inpsCreate();
int inpsUpdate();

// inpc.cpp
extern unsigned int inpcInput;
int inpcCreate();

// stated.cpp
extern int drvSaveAll;
int statedAuto(int save);
int statedLoad(int slot);
int statedSave(int slot);

// numdial.cpp
void colorAdjustDialog(HWND);
void cpuClockDialog(HWND);
void aspectSetDialog(HWND);

// sfactd.cpp
int shotFactoryCreate();

// roms.cpp
extern bool avOk;
extern bool rescanRoms;
int createROMInfo();

// miscpaths.cpp
enum ePath {
	PATH_PREVIEW = 0,
	PATH_CHEAT,
	PATH_SCREENSHOT,
	PATH_SAVESTATE,
	PATH_RECORDING,
	PATH_SKIN,
	PATH_IPS,
	PATH_TITLE,
	PATH_FLYER,
	PATH_SCORE,
	PATH_SELECT,
	PATH_GAMEOVER,
	PATH_BOSS,
	PATH_ICON,
	PATH_SUM
};
extern wchar_t miscPaths[PATH_SUM][MAX_PATH];
int miscDirCreate(HWND);
const wchar_t* getMiscPath(unsigned int dirType);
const wchar_t* getMiscArchiveName(unsigned int dirType);

extern wchar_t appRomPaths[DIRS_MAX][MAX_PATH];
int romsDirCreate(HWND);
void pathSheetCreate(HWND);

// skin.cpp
extern bool useGdip;		// use GDI+
extern int randomSkin;
extern bool vidUsePlaceholder;
extern wchar_t skinPlaceHolder[MAX_PATH];
HBITMAP loadSkin(HWND hWnd);
void randomSelectSkin();
int selectSkin();
void paintSkin(HWND hWnd);

// fba_kaillera.cpp
int kailleraInitInput();
int kailleraGetInput();

extern int kNetGame;
void doNetGame();
bool FBAKailleraInit();
void FBAKailleraEnd();

// replay.cpp
extern int replayStatus;
extern bool replayReadOnly;
extern bool frameCounterDisplay;
int recordInput();
int replayInput();
int startRecord();
int startReplay(const wchar_t* filename = NULL);
void stopReplay();
int freezeInput(unsigned char** buf, int* size);
int unfreezeInput(const unsigned char* buf, int size);

// memcard.cpp
extern int nMemoryCardStatus;	// & 1 = file selected, & 2 = inserted
int memCardCreate();
int memCardSelect();
int memCardInsert();
int memCardEject();
int memCardToggle();

// ----------------------------------------------------------------------------
// AVI recording

extern int aviStatus;
extern int aviIntAudio;
int aviStart();
int aviRecordFrame(int draw);
int aviStop();
void aviSetBuffer(unsigned char* buffer);

// ----------------------------------------------------------------------------
// Audit
int getAllRomsetInfo();
void auditPrepare();
int auditRomset(unsigned index);
void auditCleanup();

#endif
